package view.inventory;

import java.awt.Color;
import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.table.TableCellRenderer;
import main.ServicesList;
import model.inventory.ItemHpp;
import model.publics.Supplier;
import org.apache.log4j.Logger;
import utility.Constants;
import utility.NameValueList;
import utility.com.CheckboxTableRenderer;
import view.lookup.LookupSimpleFrm;


public class CopyHargaFrm extends javax.swing.JFrame {

    private static final int COL_NO  = 0;
    private static final int COL_KODE  = 1;
    private static final int COL_NAMA  = 2;
    private static final int COL_AKTIF = 3;
    
    private static final int SPL_OLD = 0;
    private static final int SPL_NEW = 1;
    
    final JCheckBox aktiveCE = new JCheckBox();
    
    private CopyHargaTM itemTM;
    private List<ItemHpp> itemHpps, saveItemHpps;
    
    private Supplier oldSupplier;
    private Supplier newSupplier;
    
    private static Logger log = Logger.getLogger(CopyHargaFrm.class);
    private Object oldValue, newValue;
    
    public CopyHargaFrm() {
        initComponents();
        initComponentsRules();
    }
    
    public void execute(boolean withVisible, int id) {
        setLocationRelativeTo(null);
        initForm();
        if (withVisible) { setVisible(true); }
    }
    
    private void initComponentsRules() {
        btnNew.registerKeyboardAction(btnNew.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, false)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, false), JComponent.WHEN_FOCUSED);
 
        btnNew.registerKeyboardAction(btnNew.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, true)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, true), JComponent.WHEN_FOCUSED);
        
       
        btnSave.registerKeyboardAction(btnSave.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, false)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, false), JComponent.WHEN_FOCUSED);
 
        btnSave.registerKeyboardAction(btnSave.getActionForKeyStroke(
            KeyStroke.getKeyStroke(KeyEvent .VK_SPACE, 0, true)), KeyStroke.getKeyStroke(KeyEvent .VK_ENTER, 0, true), JComponent.WHEN_FOCUSED);
        
        txtOld.addKeyListener(new ActionKeyListener());
        txtNew.addKeyListener(new ActionKeyListener());
        
        txtNew.addFocusListener(new ActionFocusGained());
        txtOld.addFocusListener(new ActionFocusGained());
    }
    
    private void initGrid() {
        itemTM = new CopyHargaTM(itemHpps);
        grid.setModel(itemTM);

        grid.getColumnModel().getColumn(COL_AKTIF).setCellRenderer(new CheckboxTableRenderer());
        grid.getColumnModel().getColumn(COL_AKTIF).setCellEditor(new DefaultCellEditor (aktiveCE));
        grid.getColumnModel().getColumn(COL_NO).setMaxWidth(30);
        grid.getColumnModel().getColumn(COL_NO).setMinWidth(30);
        grid.getColumnModel().getColumn(COL_NO).setPreferredWidth(30);
        
        grid.getColumnModel().getColumn(COL_AKTIF).setMaxWidth(20);
        grid.getColumnModel().getColumn(COL_AKTIF).setMinWidth(20);
        grid.getColumnModel().getColumn(COL_AKTIF).setPreferredWidth(20);
        
        grid.getColumnModel().getColumn(COL_KODE).setMaxWidth(90);
        grid.getColumnModel().getColumn(COL_KODE).setMinWidth(90);
        grid.getColumnModel().getColumn(COL_KODE).setPreferredWidth(90);
        
        //look style
        final TableCellRenderer header = grid.getTableHeader().getDefaultRenderer();
        grid.getTableHeader().setDefaultRenderer(new TableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                JLabel lbl = (JLabel) header.getTableCellRendererComponent(table, 
                      value, isSelected, hasFocus, row, column);
                lbl.setBorder(BorderFactory.createEmptyBorder(5,1,5,1));   
   
                switch (column) {
                    case COL_NO: lbl.setHorizontalAlignment(SwingConstants.RIGHT); break;
                    case COL_AKTIF: lbl.setHorizontalAlignment(SwingConstants.CENTER); break;
                    default: lbl.setHorizontalAlignment(SwingConstants.LEFT); break;   
                }
                lbl.setForeground(Color.WHITE);
                lbl.setBackground(Color.DARK_GRAY);
                return lbl;
            }
        });
        grid.setGridColor(Color.LIGHT_GRAY);
    }
    
    private void initForm() {
        txtNew.setText("");
        txtOld.setText("");
        txtNewName.setText("");
        txtOldName.setText("");
        itemHpps = new ArrayList<>();
        oldSupplier = null;
        newSupplier = null;
        rdCopy.setSelected(true);
        initGrid();
    }

    private void saveData() {
        saveItemHpps = new ArrayList<>();
        for (ItemHpp hpp : itemHpps) {
            if(hpp.isSelect()) { saveItemHpps.add(hpp); }
        }
                
        boolean saved;
        saved = ServicesList.getItemHppService().save(itemHpps, newSupplier.getId(), rdCopy.isSelected());
        
        if (!saved) {
            JOptionPane.showMessageDialog(this, "Data gagal disimpan.", "Error",JOptionPane.ERROR_MESSAGE);
        }
        
        initButtonState(!saved);
    }
    
    private void validasi() {
        boolean valid = oldSupplier != null && newSupplier != null ? true:false;
        
        if (!valid) {
            JOptionPane.showMessageDialog(this, "Inputan blm lengkap.!", "Warning",JOptionPane.WARNING_MESSAGE);}
        
        if (valid) { saveData(); }
    }
    
    private void loadData() {
        if(oldSupplier!=null && newSupplier!=null) {
            Map<NameValueList, Object> params = new HashMap<>();
            
            params.put(new NameValueList("hpp.id.supplierId", Constants.OPERATOR_EQUAL), oldSupplier.getId()); 
            params.put(new NameValueList(null, Constants.OPERATOR_CUSTOM), 
                "(hpp.id.itemId not in "+
                    "(select distinct isp.id.itemId from ItemSupplier isp "+
                    "where isp.id.supplierId = "+newSupplier.getId()+"))");
            
            params.put(new NameValueList(null, Constants.OPERATOR_CUSTOM), 
                "(hpp.id.itemId in "+
                    "(select distinct hpp.id.itemId from ItemHpp hpp "+
                    "where hpp.id.supplierId = "+oldSupplier.getId()+"))");
             
            params.put(new NameValueList(null, Constants.OPERATOR_ORDERBY), "hpp.item.nama"); 
            itemHpps = ServicesList.getItemHppService().getAll(params);
            initGrid();
            moveNext();
        }
    }
    
    private void lookupMaster(int purpose, String param) {
        Object object = new LookupSimpleFrm().execute(Constants.LOOKUP_SUPPLIER, param); 
        if (object != null) { setMaster(purpose, object); }
    }
    
    private void setMaster(int purpose, Object object) {
        if (object != null) {
            switch (purpose) {
                case SPL_NEW:
                    newSupplier = (Supplier) object;
                    txtNew.setText(newSupplier.getKode());
                    txtNewName.setText(newSupplier.getNama());
                    loadData();
                    break;
                    
                case SPL_OLD:
                    oldSupplier = (Supplier) object;
                    txtOld.setText(oldSupplier.getKode());
                    txtOldName.setText(oldSupplier.getNama());
                    loadData();
                    break;
                    
                default: break;    
            }
        }
    }
    
    private void getMaster(int purpose, String kode) {
         Supplier supplier = ServicesList.getSupplierService().getSupplier(kode);
         if (supplier != null) {setMaster(purpose, supplier); }
         else { lookupMaster(purpose, purpose == SPL_NEW ? txtNew.getText() : txtOld.getText()); }
    }
    
    private void initButtonState(boolean status) {
        btnSave.setEnabled(status);
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup2 = new javax.swing.ButtonGroup();
        jToolBar1 = new javax.swing.JToolBar();
        btnNew = new javax.swing.JButton();
        btnSave = new javax.swing.JButton();
        txtOld = new javax.swing.JTextField();
        txtNew = new javax.swing.JTextField();
        txtNewName = new javax.swing.JTextField();
        txtOldName = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        rdCopy = new javax.swing.JRadioButton();
        rdMove = new javax.swing.JRadioButton();
        btnSelect = new javax.swing.JButton();
        btnSelectAll = new javax.swing.JButton();
        jsp = new javax.swing.JScrollPane();
        grid = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jToolBar1.setFloatable(false);
        jToolBar1.setRollover(true);
        jToolBar1.setMaximumSize(new java.awt.Dimension(32767, 20));
        jToolBar1.setSize(this.getWidth(), 50);

        btnNew.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edit_add.png"))); // NOI18N
        btnNew.setText("Tambah");
        btnNew.setFocusable(false);
        btnNew.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnNew.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNewActionPerformed(evt);
            }
        });
        jToolBar1.add(btnNew);

        btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edit.png"))); // NOI18N
        btnSave.setText("Save");
        btnSave.setFocusable(false);
        btnSave.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnSave.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });
        jToolBar1.add(btnSave);

        txtOld.setName("txtOld"); // NOI18N

        txtNew.setName("txtNew"); // NOI18N

        txtNewName.setEditable(false);
        txtNewName.setFocusable(false);
        txtNewName.setName("txtNewName"); // NOI18N

        txtOldName.setEditable(false);
        txtOldName.setFocusable(false);
        txtOldName.setName("txtOldName"); // NOI18N

        jLabel1.setText("Supplier Lama :");

        jLabel2.setText("Supplier Baru :");

        buttonGroup2.add(rdCopy);
        rdCopy.setText("Copy");
        rdCopy.setName("rdCopy"); // NOI18N

        buttonGroup2.add(rdMove);
        rdMove.setText("Move");
        rdMove.setName("rdMove"); // NOI18N

        btnSelect.setText("Select All");
        btnSelect.setName("btnSelect"); // NOI18N
        btnSelect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSelectActionPerformed(evt);
            }
        });

        btnSelectAll.setText("Deselect All");
        btnSelectAll.setName("btnSelectAll"); // NOI18N
        btnSelectAll.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSelectAllActionPerformed(evt);
            }
        });

        jsp.setName("jsp"); // NOI18N

        grid.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        grid.setName("grid"); // NOI18N
        jsp.setViewportView(grid);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.TRAILING))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(txtNew, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(txtOld, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(txtNewName)
                            .addComponent(txtOldName)))
                    .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 494, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jsp, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(rdCopy)
                            .addComponent(rdMove)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(btnSelect, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(btnSelectAll, javax.swing.GroupLayout.Alignment.TRAILING)))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtOld, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtOldName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtNewName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(28, 28, 28)
                        .addComponent(rdCopy)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(rdMove)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(btnSelect)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnSelectAll)
                        .addContainerGap(82, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jsp, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                        .addContainerGap())))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewActionPerformed
        initForm();
        txtOld.requestFocus();
    }//GEN-LAST:event_btnNewActionPerformed

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
        validasi();
    }//GEN-LAST:event_btnSaveActionPerformed

    private void btnSelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSelectActionPerformed
        for (ItemHpp hpp : itemHpps) {
            hpp.setSelect(true);
        }
        itemTM.fireTableRowsUpdated(0, itemHpps.size());
    }//GEN-LAST:event_btnSelectActionPerformed

    private void btnSelectAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSelectAllActionPerformed
        for (ItemHpp hpp : itemHpps) {
            hpp.setSelect(false);
        }
        itemTM.fireTableRowsUpdated(0, itemHpps.size());
    }//GEN-LAST:event_btnSelectAllActionPerformed

    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnNew;
    private javax.swing.JButton btnSave;
    private javax.swing.JButton btnSelect;
    private javax.swing.JButton btnSelectAll;
    private javax.swing.ButtonGroup buttonGroup2;
    private javax.swing.JTable grid;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JScrollPane jsp;
    private javax.swing.JRadioButton rdCopy;
    private javax.swing.JRadioButton rdMove;
    private javax.swing.JTextField txtNew;
    private javax.swing.JTextField txtNewName;
    private javax.swing.JTextField txtOld;
    private javax.swing.JTextField txtOldName;
    // End of variables declaration//GEN-END:variables

    @Override
    public void setVisible(boolean value) {
        super.setVisible(value);
        txtOld.requestFocusInWindow();
    }
    
    private void moveNext() {
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.focusNextComponent();
    }
    
    private void setTableLookStyle() {
        
    }
    
    class ActionKeyListener implements KeyListener {
        @Override public void keyTyped(KeyEvent e) {} 
        @Override public void keyReleased(KeyEvent e) {}
        @Override public void keyPressed(KeyEvent e) {
            switch (e.getKeyCode()) { 
                case KeyEvent.VK_F2: 
                    switch(e.getComponent().getName()) {
                        case "txtOld": lookupMaster(SPL_OLD, txtOld.getText()); break;
                        case "txtNew": lookupMaster(SPL_NEW, txtNew.getText()); break;
                    };
                break;  
                
                case KeyEvent.VK_ENTER: 
                    switch(e.getComponent().getName()) {
                        case "txtOld": 
                            newValue = txtOld.getText();
                            if (!newValue.equals(oldValue)) { getMaster(SPL_OLD, txtOld.getText()); }
                            else {moveNext();}
                            break;
                            
                        case "txtNew": 
                            newValue = txtNew.getText();
                            if (!newValue.equals(oldValue)) { getMaster(SPL_NEW, txtNew.getText()); }
                            else {moveNext();}
                            break;
                                
                       default: moveNext(); break;
                    };
                break;      
            }
        }
    }
    
    class ActionFocusGained implements FocusListener {
        @Override public void focusGained(FocusEvent e) { 
            Component componen = (Component) e.getSource(); 
            if (componen instanceof JTextField) { oldValue = ((JTextField) componen).getText();
            }else if (componen instanceof JCheckBox) { oldValue = ((JCheckBox) componen).isSelected(); }
        }
        
        @Override public void focusLost(FocusEvent e) {
            Component componen = (Component) e.getSource(); 
            if (componen instanceof JTextField) { newValue = ((JTextField) componen).getText();
            }else if (componen instanceof JCheckBox) { newValue = ((JCheckBox) componen).isSelected(); }
            
            if (!newValue.equals(oldValue)) { initButtonState(true); }
        }
    }
}
